package com.ly.pool;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

public class Decompose {

    static List<Integer> datalist = new ArrayList<>();

    static int datasum = 10000;

    static int dataGroup = 10;

    static int subDataGroup = 5;

    public static void main(String[] args) throws Exception {

        //添加数据
        for (int i = 0; i <datasum ; i++) {
            datalist.add(i);
        }

        //数据处理
        dataTask(datalist);


    }

    private static Integer dataTask(List<Integer> datalist) throws Exception {
        /**将数据第一次分割   将全部数据分为10个元素一组  分为1000组
         *  结果为{[0,1,2,3,4],[5,6,7,8,9],[10,11,12,13,14]...}
         */
        int size = datalist.size()/dataGroup;
        List<List<Integer>> sublist = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            sublist.add(datalist.subList(i*dataGroup,(i+1)*dataGroup));
        }
        //System.out.println("sublist"+ Arrays.toString(sublist.toArray()));


        /**
         * 将1000组数据进行二次分割
         * 1000组 每5组 为一线程  共200线
         * 结果为{[0(00,01,02,03,04)),1(05,06,07,08,09),2(10-14),3(15-19),4(20-25)],...}
         */
        int length = sublist.size()/subDataGroup;//1000/5

        //创建定长线程池  一个参数  创建一个线程池，该线程池重用固定数量的从共享无界队列中运行的线程。
        ExecutorService executorService = Executors.newFixedThreadPool(length);

        System.out.println("创建线程池"+length);

        //声明result  用来记录返回值
        int result = 0;
        for (int k = 0; k < length; k++) {
            List<List<Integer>> group = sublist.subList(k * subDataGroup, (k + 1) * subDataGroup);
            //创建功能类实现callable接口 分析数据并获取分析结果
            CallableTest callableTest = new CallableTest(group);
            /**
             * executorService.submit方法描述:提交一个可运行的任务执行，并返回一个表示该任务的未来。
             *
             * 类似FutureTask线程创建方法,创建FutureTask类 构造参数传入Callable接口
             * 返回Future接口类型值
             *
             * 此类中CallableTest类实现Callable接口
             * 将CallableTest类传入submit方法 返回Future接口类型值
             * 返回值调用get方法获取结果值
             */
            Future<Integer> submit = executorService.submit(callableTest);
            result=submit.get();
        }

        System.out.println("共计处理数据"+result);
        return null;
    }


}
class CallableTest implements Callable<Integer>{

    List<List<Integer>> sublist = null;

    public CallableTest(List<List<Integer>> sublist){
        this.sublist = sublist;
    }

    /**
     * 一个AtomicInteger用于诸如原子增量计数器的应用程序中，不能用作Integer的替代品 。
     * incrementAndGet()原有增加当前值
     */
    static AtomicInteger sumcount = new AtomicInteger();

    @Override
    public Integer call() throws Exception {

        AtomicInteger success = new AtomicInteger();
        AtomicInteger fair = new AtomicInteger();

        try {
            for (List<Integer> ilist : sublist) {
                for (Integer inum : ilist) {
                    //将 Integer的值作为 int
                    if (inum.intValue() % 2 ==0){
                        //成功
                        success.incrementAndGet();
                        sumcount.incrementAndGet();
                    }else {
                        fair.incrementAndGet();
                        //错误处理
                        if ((inum.intValue()+1)%2==0){
                            sumcount.incrementAndGet();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println(Thread.currentThread().getName()+"==>成功:"+success.get()+"==>失败:"+fair.get()+ Arrays.toString(sublist.toArray()));
        }

        return sumcount.get();
    }
}